#pragma once

#include "vector2d.h"
#include "drawable.h"
#include <fstream>	// loading data from files
using namespace std;

class Map : public Drawable
{
protected:
	char ** map;
	char empty;
	Vector2D dimension;
	int numFilters;
	static const int FILTER_CHAR = 0, FILTER_COLOR = 1;
	char ** filter;
public:
	Map():map(0),numFilters(0){}
	void load(const char * file)
	{
		ifstream in(file);
		// determine the size of the map that will load
		in >> dimension.x;
		in >> dimension.y;
		// allocate the 2D array for the map
		map = new char * [dimension.y];
		for(int y = 0; y < getHeight(); ++y)
		{
			map[y] = new char [getWidth()];
		}
		// load the data into the map
		char input;
		for(int y = 0; y < getHeight(); ++y)
		{
			for(int x = 0; x < getWidth(); ++x)
			{
				input = in.get();
				// ignore bad characers...
				if(input == '\r' || input == '\n')
					--x;
				else
					map[y][x] = input;
			}
		}
		if(in.good())
		{
			in >> numFilters;
			filter = new char * [numFilters];
			int color;
			for(int i = 0; i < numFilters; ++i)
			{
				filter[i] = new char[2];
				in >> filter[i][FILTER_CHAR];
				in >> color;
				filter[i][FILTER_COLOR] = color;
			}
		}
		in.close();
	}
	void release()
	{
		if(map)
		{
			for(int y = 0; y < getHeight(); ++y)
			{
				delete map[y];
			}
			delete [] map;
			map = 0;
			dimension.y = 0;
			dimension.x = 0;
		}
	}
	~Map()
	{
		release();
	}
	char get(int x, int y)
	{
		return map[y][x];
	}
	int getWidth(){return dimension.x;}
	int getHeight(){return dimension.y;}
	Map(Vector2D size, char empty)
		// initializer list
		:dimension(size),empty(empty),map(0)
	// function body
	{
	}
	/** render code */
	void draw()
	{
		COORD origin = {0,0};
		SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),
			origin);
		char c, color;
		bool colorFound;
		// draw the map
		for(int row = 0; row < getHeight(); ++row)
		{
			for(int col = 0; col < getWidth(); ++col)
			{
				c = get(col, row);
				colorFound = false;
				color = Character::Colors::LtGray;
				for(int i = 0; i < numFilters
					&& !colorFound; ++i)
				{
					if(c == filter[i][FILTER_CHAR])
					{
						color = filter[i][FILTER_COLOR];
						colorFound = true;
					}
				}
				// draw the filterd color
				SetConsoleTextAttribute(
					GetStdHandle(STD_OUTPUT_HANDLE),
					color);
				putchar( c );
				// reset
				SetConsoleTextAttribute(
					GetStdHandle(STD_OUTPUT_HANDLE),
					Character::Colors::LtGray);
			}
			putchar('\n');
		}

	}
};

